home *** CD-ROM | disk | FTP | other *** search
/ Internet Info 1994 March / Internet Info CD-ROM (Walnut Creek) (March 1994).iso / networking / ip / ka9q / osrc.arc / PATHNAME.C < prev    next >
Encoding:
C/C++ Source or Header  |  1989-04-16  |  2.3 KB  |  93 lines

  1. #include "global.h"
  2.  
  3. static void crunch();
  4.  
  5. /* Given a working directory and an arbitrary pathname, resolve them into
  6.  * an absolute pathname. Memory is allocated for the result, which
  7.  * the caller must free
  8.  */
  9. char *
  10. pathname(cd,path)
  11. char *cd;    /* Current working directory */
  12. char *path;    /* Pathname argument */
  13. {
  14.     register char *buf;
  15.  
  16.     if(cd == NULLCHAR || path == NULLCHAR)
  17.         return NULLCHAR;
  18.  
  19.     /* Strip any leading white space on args */
  20.     while(*cd == ' ' || *cd == '\t')
  21.         cd++;
  22.     while(*path == ' ' || *path == '\t')
  23.         path++;
  24.  
  25.     /* Allocate and initialize output buffer; user must free */
  26.     buf = malloc((unsigned)strlen(cd) + strlen(path) + 10);    /* fudge factor */
  27.     if(buf == NULLCHAR)
  28.         return NULLCHAR;
  29.     buf[0] = '\0';
  30.  
  31.     /* Interpret path relative to cd only if it doesn't begin with "/" */
  32.     if(path[0] != '/')
  33.         crunch(buf,cd);
  34.  
  35.     crunch(buf,path);
  36.  
  37.     /* Special case: null final path means the root directory */
  38.     if(buf[0] == '\0'){
  39.         buf[0] = '/';
  40.         buf[1] = '\0';
  41.     }
  42.     return buf;
  43. }
  44.  
  45. /* Process a path name string, starting with and adding to
  46.  * the existing buffer
  47.  */
  48. static void
  49. crunch(buf,path)
  50. char *buf;
  51. register char *path;
  52. {
  53.     register char *cp;
  54.     
  55.  
  56.     cp = buf + strlen(buf);    /* Start write at end of current buffer */
  57.     
  58.     /* Now start crunching the pathname argument */
  59.     for(;;){
  60.         /* Strip leading /'s; one will be written later */
  61.         while(*path == '/')
  62.             path++;
  63.         if(*path == '\0')
  64.             break;        /* no more, all done */
  65.         /* Look for parent directory references, either at the end
  66.          * of the path or imbedded in it
  67.          */
  68.         if(strcmp(path,"..") == 0 || strncmp(path,"../",3) == 0){
  69.             /* Hop up a level */
  70.             if((cp = strrchr(buf,'/')) == NULLCHAR)
  71.                 cp = buf;    /* Don't back up beyond root */
  72.             *cp = '\0';        /* In case there's another .. */
  73.             path += 2;        /* Skip ".." */
  74.             while(*path == '/')    /* Skip one or more slashes */
  75.                 path++;
  76.         /* Look for current directory references, either at the end
  77.          * of the path or imbedded in it
  78.          */
  79.         } else if(strcmp(path,".") == 0 || strncmp(path,"./",2) == 0){
  80.             /* "no op" */
  81.             path++;            /* Skip "." */
  82.             while(*path == '/')    /* Skip one or more slashes */
  83.                 path++;
  84.         } else {
  85.             /* Ordinary name, copy up to next '/' or end of path */
  86.             *cp++ = '/';
  87.             while(*path != '/' && *path != '\0')
  88.                 *cp++ = *path++;
  89.         }
  90.     }
  91.     *cp++ = '\0';
  92. }
  93.